module transmitter (
    input wire sys_clk,
    input wire rst_n,
    input wire clken,
    output reg txclk_gen_ena,
    input wire [7:0] din,
    input wire wr_en,
    output reg tx,
    output wire tx_busy
);

  parameter integer STATE_IDLE = 2'b00;
  parameter integer STATE_START = 2'b01;
  parameter integer STATE_DATA = 2'b10;
  parameter integer STATE_STOP = 2'b11;

  reg [7:0] data;
  reg [2:0] bitpos;
  reg [1:0] state;

  always @(posedge sys_clk, negedge rst_n) begin
    if (~rst_n) begin
      tx <= 1'b1;
      data <= 8'h00;
      bitpos <= 3'h0;
      state <= STATE_IDLE;
      txclk_gen_ena <= 1'b0;
    end else begin
      case (state)
        STATE_IDLE: begin
          if (wr_en) begin
            state <= STATE_START;
            data <= din;
            bitpos <= 3'h0;
            txclk_gen_ena <= 1'b1;
          end
        end
        STATE_START: begin
          if (clken) begin
            tx <= 1'b0;
            state <= STATE_DATA;
          end
        end
        STATE_DATA: begin
          if (clken) begin
            if (bitpos == 3'h7) state <= STATE_STOP;
            else bitpos <= bitpos + 3'h1;
            tx <= data[bitpos];
          end
        end
        STATE_STOP: begin
          if (clken) begin
            tx <= 1'b1;
            state <= STATE_IDLE;
            txclk_gen_ena <= 1'b1;
          end
        end
        default: begin
          tx <= 1'b1;
          state <= STATE_IDLE;
          txclk_gen_ena <= 1'b0;
        end
      endcase
    end
  end

  assign tx_busy = (state != STATE_IDLE);

endmodule
